package com.koron.operation.classes.form.service.impl;


import com.koron.operation.classes.form.bean.constants.ClassesFormUtil;
import com.koron.operation.classes.form.bean.dto.ClassesFormChangeDTO;
import com.koron.operation.classes.form.bean.po.ClassesFormChange;
import com.koron.operation.classes.form.bean.po.ClassesFormShift;
import com.koron.operation.classes.form.bean.po.ClassesFormTakeover;
import com.koron.operation.classes.form.bean.query.ClassesFormRecordQuery;
import com.koron.operation.classes.form.bean.vo.ClassesFormChangeVO;
import com.koron.operation.classes.form.bean.vo.ClassesFormRecordVO;
import com.koron.operation.classes.form.mapper.ClassesFormChangeMapper;
import com.koron.operation.classes.form.service.ClassesFormChangeService;
import com.koron.operation.classes.form.service.ClassesFormRecordService;
import com.koron.operation.classes.form.service.ClassesFormShiftService;
import com.koron.operation.classes.form.service.ClassesFormTakeoverService;
import lombok.RequiredArgsConstructor;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 班别调整表(ClassesFormChange)表服务实现类
 *
 * @author jzp
 * @since 2023-05-22 09:48:16
 */
@Service
@RequiredArgsConstructor
public class ClassesFormChangeServiceImpl implements ClassesFormChangeService {

    private final ClassesFormTakeoverService classesFormTakeoverService;
    private final ClassesFormShiftService classesFormShiftService;
    private final ClassesFormRecordService classesFormRecordService;

    /**
     * 通过ID查询单条数据
     */
    @Override
    @TaskAnnotation("getById")
    public ClassesFormChangeVO getVoById(SessionFactory factory, String id) {
        ClassesFormChangeMapper mapper = factory.getMapper(ClassesFormChangeMapper.class);
        return mapper.selectVoById(id);
    }

    @Override
    @TaskAnnotation("getVoByShiftId")
    public ClassesFormChangeVO getVoByShiftId(SessionFactory factory, String shiftId) {
        ClassesFormChange query = new ClassesFormChange();
        query.setShiftId(shiftId);
        List<ClassesFormChangeVO> list = list(factory, query);
        if (list == null) {
            return null;
        }
        if (list.size() == 1) {
            return list.get(0);
        }
        if (list.size() > 1) {
            return list.get(list.size() - 1);
        }
        return null;
    }

    @Override
    @TaskAnnotation("listByFormId")
    public List<ClassesFormChangeVO> listByFormId(SessionFactory factory, String formId) {
        ClassesFormChange query = new ClassesFormChange();
        query.setFormId(formId);
        return list(factory, query);
    }

    @Override
    @TaskAnnotation("getDtoById")
    public ClassesFormChangeDTO getDtoById(SessionFactory factory, String id) {
        ClassesFormChangeMapper mapper = factory.getMapper(ClassesFormChangeMapper.class);
        ClassesFormChangeDTO classesFormChangeDTO = mapper.selectDtoById(id);
        // 加班
        if ("0".equals(classesFormChangeDTO.getChangeType())) {
            ClassesFormRecordQuery query = new ClassesFormRecordQuery();
            query.setId(classesFormChangeDTO.getShiftId());
            List<ClassesFormRecordVO> classesFormRecordVOS = classesFormRecordService.listVo(factory, query);
            classesFormChangeDTO.setRecordList(classesFormRecordVOS);
        }
        return classesFormChangeDTO;
    }

    @Override
    @TaskAnnotation("getDtoByShiftId")
    public ClassesFormChangeDTO getDtoByShiftId(SessionFactory factory, String shiftId) {
        ClassesFormChangeVO classesFormChangeVO = getVoByShiftId(factory, shiftId);
        if (classesFormChangeVO == null) {
            return null;
        }
        return getDtoById(factory, classesFormChangeVO.getId());
    }

    /**
     * 查询所有数据
     */
    @Override
    @TaskAnnotation("list")
    public List<ClassesFormChangeVO> list(SessionFactory factory, ClassesFormChange classesFormChange) {
        ClassesFormChangeMapper mapper = factory.getMapper(ClassesFormChangeMapper.class);
        return mapper.selectList(classesFormChange);
    }

    @Override
    @TaskAnnotation("listDetail")
    public List<ClassesFormChangeDTO> listDetail(SessionFactory factory, ClassesFormChange classesFormChange) {
        List<ClassesFormChangeVO> list = list(factory, classesFormChange);
        if (list == null) {
            return null;
        }
        return list.stream().map(vo -> getDtoById(factory, vo.getId())).collect(Collectors.toList());
    }

    /**
     * 新增数据
     */
    @Override
    @TaskAnnotation("save")
    public boolean save(SessionFactory factory, ClassesFormChange classesFormChange) {
        if (classesFormChange.getStatus() == null) {
            classesFormChange.setStatus(ClassesFormUtil.Status.DRAFT);
        }
        if (Objects.equals(classesFormChange.getStatus(), ClassesFormUtil.Status.DRAFT)) {
            classesFormShiftService.updateChangeStatus(factory, classesFormChange.getShiftId(), classesFormChange.getStatus());
        }
        ClassesFormChangeMapper mapper = factory.getMapper(ClassesFormChangeMapper.class);
        return mapper.insertOrUpdate(classesFormChange) > 0;
    }

    @Override
    @TaskAnnotation("saveDto")
    public boolean saveDto(SessionFactory factory, ClassesFormChangeDTO classesFormChangeDTO) {
        // 1. 保存主表
        save(factory, classesFormChangeDTO);

        // 2. 保存接班信息
        classesFormTakeoverService.removeByChangeId(factory, classesFormChangeDTO.getId());
        List<ClassesFormTakeover> takeoverList = classesFormChangeDTO.getTakeoverList();
        if (takeoverList == null) {
            return true;
        }
        takeoverList.forEach(e -> {
            e.setChangeId(classesFormChangeDTO.getId());
            e.setShiftId(classesFormChangeDTO.getShiftId());
            e.setChangeStatus(classesFormChangeDTO.getStatus());
        });
        classesFormTakeoverService.saveBatch(factory, classesFormChangeDTO.getTakeoverList());
        return true;
    }

    /**
     * 修改数据
     */
    @Override
    @TaskAnnotation("update")
    public boolean update(SessionFactory factory, ClassesFormChange classesFormChange) {
        ClassesFormChangeMapper mapper = factory.getMapper(ClassesFormChangeMapper.class);
        return mapper.update(classesFormChange) > 0;
    }

    @Override
    @TaskAnnotation("updateStatus")
    public boolean updateStatus(SessionFactory factory, String id, String status) {
        ClassesFormChange classesFormChange = new ClassesFormChange();
        classesFormChange.setId(id);
        classesFormChange.setStatus(status);
        update(factory, classesFormChange);
        return classesFormTakeoverService.updateChangeStatusByChangeId(factory, id, status);
    }

    @Override
    @TaskAnnotation("submit")
    public boolean submit(SessionFactory factory, ClassesFormChangeDTO classesFormChangeDTO, String currNodeCode) {
        // 草稿
        if (currNodeCode == null || currNodeCode.contains(ClassesFormUtil.Status.DRAFT)) {
            updateStatus(factory, classesFormChangeDTO.getId(), ClassesFormUtil.Status.DRAFT);
            classesFormShiftService.updateChangeStatus(factory, classesFormChangeDTO.getShiftId(), ClassesFormUtil.Status.DRAFT);
            return true;
        }
        // 调整确认
        else if (currNodeCode.contains(ClassesFormUtil.Status.CHANGE_CONFIRM)) {
            updateStatus(factory, classesFormChangeDTO.getId(), ClassesFormUtil.Status.CHANGE_CONFIRM);
            classesFormShiftService.updateChangeStatus(factory, classesFormChangeDTO.getShiftId(), ClassesFormUtil.Status.CHANGE_CONFIRM);
            return true;
        }
        // 待审核
        else if (currNodeCode.contains(ClassesFormUtil.Status.WAIT_REVIEW)) {
            updateStatus(factory, classesFormChangeDTO.getId(), ClassesFormUtil.Status.WAIT_REVIEW);
            classesFormShiftService.updateChangeStatus(factory, classesFormChangeDTO.getShiftId(), ClassesFormUtil.Status.WAIT_REVIEW);
            return true;
        }
        // 已归档
        else if (currNodeCode.equals("END") || currNodeCode.contains(ClassesFormUtil.Status.ARCHIVED)) {
            updateStatus(factory, classesFormChangeDTO.getId(), ClassesFormUtil.Status.ARCHIVED);
            classesFormShiftService.updateChangeStatus(factory, classesFormChangeDTO.getShiftId(), ClassesFormUtil.Status.ARCHIVED);
            String changeType = classesFormChangeDTO.getChangeType();
            // 加班
            if ("0".equals(changeType)) {
                changeShift(factory,
                        classesFormChangeDTO.getShiftId(),
                        classesFormChangeDTO.getClassesStartTimeAfter(),
                        classesFormChangeDTO.getClassesEndTimeAfter());
            }
            // 2休假、3特殊事务申请、4调班
            else {
                if ("2".equals(changeType)) {
                    changeShift(factory,
                            classesFormChangeDTO.getShiftId(),
                            classesFormChangeDTO.getClassesStartTimeAfter(),
                            classesFormChangeDTO.getClassesEndTimeAfter(),
                            classesFormChangeDTO.getClassesItemIdAfter(),
                            classesFormChangeDTO.getClassesItemNameAfter());
                } else {
                    changeShift(factory,
                            classesFormChangeDTO.getShiftId(),
                            classesFormChangeDTO.getClassesItemIdAfter(),
                            classesFormChangeDTO.getClassesItemNameAfter());
                }
                // 更新接班人信息
                List<ClassesFormTakeover> takeoverList = classesFormChangeDTO.getTakeoverList();
                if (takeoverList == null) {
                    return true;
                }
                for (ClassesFormTakeover classesFormTakeover : takeoverList) {
                    // 如果有接班人有班次，则修改
                    if (classesFormTakeover.getShiftIdAfter() == null) {
                        continue;
                    }
                    // 加班
                    if ("0".equals(classesFormTakeover.getChangeType())) {
                        changeShift(factory,
                                classesFormTakeover.getShiftIdAfter(),
                                classesFormTakeover.getClassesStartTimeAfter(),
                                classesFormTakeover.getClassesEndTimeAfter());
                    }
                    // 调班
                    else {
                        changeShift(factory,
                                classesFormTakeover.getShiftIdAfter(),
                                classesFormTakeover.getClassesItemIdAfter(),
                                classesFormTakeover.getClassesItemNameAfter());
                    }
                }
            }
        }
        return false;
    }

    /**
     * 休假等
     */
    private void changeShift(SessionFactory factory,
                             String shiftId,
                             Date overStartTime,
                             Date overEndTime,
                             String changeItemId,
                             String changeItemName) {
        ClassesFormShift classesFormShift = new ClassesFormShift();
        classesFormShift.setId(shiftId);
        classesFormShift.setOverStartTime(overStartTime);
        classesFormShift.setOverEndTime(overEndTime);
        classesFormShift.setOverDuration("");
        classesFormShift.setChangeItemId(changeItemId);
        classesFormShift.setChangeItemName(changeItemName);
        classesFormShiftService.update(factory, classesFormShift);
    }

    /**
     * 调班
     */
    private void changeShift(SessionFactory factory,
                             String shiftId,
                             String changeItemId,
                             String changeItemName) {
        ClassesFormShift classesFormShift = new ClassesFormShift();
        classesFormShift.setId(shiftId);
        classesFormShift.setChangeItemId(changeItemId);
        classesFormShift.setChangeItemName(changeItemName);
        classesFormShiftService.update(factory, classesFormShift);
    }

    /**
     * 加班
     */
    private void changeShift(SessionFactory factory,
                             String shiftId,
                             Date overStartTime,
                             Date overEndTime){
        // 查询原来的加班时间
        ClassesFormShift oriShift = classesFormShiftService.getById(factory, shiftId);
        String overDurationOri = oriShift.getOverDuration();

        ClassesFormShift classesFormShift = new ClassesFormShift();
        classesFormShift.setId(shiftId);
        String overDuration = ClassesFormUtil.betweenHour(overStartTime, overEndTime);
        classesFormShift.setOverDuration(ClassesFormUtil.plusDuration(overDurationOri, overDuration));
        classesFormShiftService.update(factory, classesFormShift);

    }


    /**
     * 通过主键删除数据
     */
    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String id) {
        ClassesFormChangeVO source = getVoById(factory, id);
        Assert.notNull(source, "未找到该数据");
        ClassesFormChangeMapper mapper = factory.getMapper(ClassesFormChangeMapper.class);
        mapper.hidden(id);
        classesFormShiftService.updateChangeStatus(factory, source.getShiftId(), "DELETED");
        classesFormTakeoverService.updateChangeStatusByChangeId(factory, id, "DELETED");
        return true;
    }

}
